package whf.framework.web.tag.ext;

import javax.servlet.jsp.JspTagException;

import org.apache.commons.lang.builder.ToStringBuilder;

import whf.framework.log.Log;
import whf.framework.log.LogFactory;
import whf.framework.web.tag.enums.SeverityEnum;

/**
 * @author wanghaifeng
 * 
 */
public abstract class BaseNestableJspTagException extends JspTagException {
	private final Class sourceClass;

	private Throwable nestedException;

	public BaseNestableJspTagException(Class source, String message) {
		super(message);
		this.sourceClass = source;

		Log log = LogFactory.getLog(source);

		if (getSeverity() == SeverityEnum.DEBUG) {
			log.debug(toString());
		} else if (getSeverity() == SeverityEnum.INFO) {
			log.info(toString());
		} else if (getSeverity() == SeverityEnum.WARN) {
			log.warn(toString());
		} else {
			// error - default
			log.error(toString());
		}

	}

	/**
	 * Instantiate a new BaseNestableJspTagException.
	 * 
	 * @param source
	 *            Class where the exception is generated
	 * @param message
	 *            message
	 * @param cause
	 *            previous Exception
	 */
	public BaseNestableJspTagException(Class source, String message,
			Throwable cause) {
		super(message);
		this.sourceClass = source;
		this.nestedException = cause;

		// log exception
		Log log = LogFactory.getLog(source);

		// choose appropriate logging method
		if (getSeverity() == SeverityEnum.DEBUG) {
			log.debug(toString(), cause);
		} else if (getSeverity() == SeverityEnum.INFO) {
			log.info(toString(), cause);
		} else if (getSeverity() == SeverityEnum.WARN) {
			log.warn(toString(), cause);
		} else {
			// error - default
			log.error(toString(), cause);
		}

	}

	/**
	 * returns the previous exception.
	 * 
	 * @return Throwable previous exception
	 */
	public Throwable getCause() {
		return this.nestedException;
	}

	/**
	 * basic toString. Returns the message plus the previous exception (if a
	 * previous exception exists).
	 * 
	 * @return String
	 */
	public String toString() {
		String className = this.sourceClass.getName();
		className = className.substring(className.lastIndexOf(".")); //$NON-NLS-1$
		return ToStringBuilder.reflectionToString(this);
		// if (this.nestedException == null)
		// {
		// return Messages.getString("NestableException.msg", //$NON-NLS-1$
		// new Object[]{className, getMessage()});
		// }
		//
		// return Messages.getString("NestableException.msgcause", //$NON-NLS-1$
		// new Object[]{className, getMessage(),
		// this.nestedException.getMessage()});
	}

	/**
	 * subclasses need to define the getSeverity method to provide correct
	 * severity for logging.
	 * 
	 * @return SeverityEnum exception severity
	 * @see org.displaytag.exception.SeverityEnum
	 */
	public abstract SeverityEnum getSeverity();

}